package language.advanced.generic;

//泛型方法示例
class genericFunction {
    //静态函数， 返回void
    public static <T> void StaticMethod(T a){
        System.out.println(("StaticMethod: "+a.toString()));
    }

    public static <T> void StaticMethod2(){
        System.out.println("StaticMethod2");
    }
    //普通函数
    //这里因为StaticFans不是泛型类，但使用了泛型类型参数，就需要将泛型参数列表放置在返回值之前
    //使用泛型方法时，通常不需要指定参数类型，因为编译器会找出这些类型，这称为类型参数推断
    //因此，对 f() 的调用看起来像普通的方法调用，而且像是被重载了无数次一样
    public <T> T[] NonStaticMethod(T a, Class<T> object, T... arg){
        System.out.println(a.getClass() == object);
        System.out.println("clazz:" + object.getName());
        System.out.println(("NonStaticMethod: "+a.toString()));
        return arg;
    }

    /**
     * 限定类型使用extends关键字指定
     * 可以使类，接口，类放在前面接口放在后面用&符号分割
     * 例如：<T extends ArrayList & Comparable<T> & Serializable>
     */
    public static <T extends Comparable<T>> T getMin(T a, T b) {
        return (a.compareTo(b) < 0) ? a : b;
    }

    public static void main(String[] args) {
        //静态方法
        genericFunction.StaticMethod("adfdsa");
        genericFunction.StaticMethod2();
        System.out.println(genericFunction.getMin(2, 4));
        System.out.println(genericFunction.getMin("a", "r"));

        //常规方法
        genericFunction staticFans = new genericFunction();
        staticFans.NonStaticMethod("123", String.class, "1","2");//加了一个<String>来指定传给<T>的值
    }

//    @Test
    public void test2() {
        genericFunction.StaticMethod("adfdsa");
    }

}  